home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 12 - 1996 / 12.06 Jun 96 / Java < prev    next >
Encoding:
Text File  |  1996-05-10  |  12.0 KB  |  251 lines  |  [TEXT/R*ch]

  1. Last month, we started exploring Java, Sun’s object-programming language that
  2. has exploded in popularity over the last year.  As a reminder, Java is similar
  3. to C++, but with some very important differences.  The Java syntax is just like
  4. C++, but without the pointer syntax.  The Java environment that runs on your
  5. machine is multi-threaded, with a low-priority thread that does automatic
  6. garbage collection.
  7. Your Java source code will reside in a file ending with the .java extension. 
  8. Your Java source code will implement a class, or a series of classes.  Depending
  9. on your development environment, you will compile the classes into a stream of
  10. Java byte-code, which will get stored in a .class file, in a series of .class
  11. files, in a .zip file, or, in some cases, in a double-clickable application
  12. file.
  13. The .class file is designed to hold a single class.  If you build a bunch of
  14. .class files, you could pay a severe penalty in wasted hard drive space.  For
  15. example, my 1-gig hard drive has a minimal file size of 17K.  If I build 100
  16. .class files, each of which is filled with 100 bytes of byte-code, I’ll end up
  17. using 1700K of hard drive space to store 10,000 bytes of byte-code.  Not very
  18. efficient, eh?
  19. The solution to this problem is the .zip file.  The .zip lets you combine a set
  20. of classes into a single file of byte-code.  Since the .zip format is based on
  21. the .zip compression format from the PC universe, you can use a zip utility
  22. (like UnZip) to peruse the classes in a .zip file.
  23. To run your byte code, you’ll need a byte-code interpreter.  There are several
  24. options for doing this.  Your development environment most likely came with some
  25. form of Java virtual machine.  It might be called “javai”, “Applet Runner”,
  26. “Applet Viewer”, or something else.  The point is, the virtual machine knows how
  27. to turn your generic Java byte-code into the equivalent machine code specific to
  28. your platform.  There are Java virtual machines written specifically for the
  29. PowerMac, and Java virtual machines written for 680x0, x86, and Unix platforms
  30. as well.  The first virtual machines came from Sun.  Other vendors are writing
  31. their own.  Check with your development environment for details on your virtual
  32. machine.
  33. Java Reference Basics
  34. Our first Java program this month demonstrates an important and potentially
  35. confusing difference between Java and C++.  As stated earlier, Java doesn’t
  36. support pointers.  When you create an object, the variable you associate with
  37. the object instance is known as a reference.  This example should make this
  38. clear.
  39. If you are using CodeWarrior or Caffeine, create a new project file using the
  40. appropriate Java stationery.  I’m using the CodeWarrior droplet stationery, so
  41. my project was named reference.µ.
  42. The CodeWarrior environment ships with a bunch of stationery, including one for
  43. Java applets and one for Java droplets.  The Java applets stationery lets you
  44. create an applet designed to be launched from an HTML file.  This is pretty
  45. standard stuff and will be supported by most every Java development environment
  46. you run into.
  47. The droplet stationery is both cool and different.  It lets you turn your Java
  48. code into a standalone application, complete with 4-byte creator code and its
  49. associated 'BNDL' resources.  And if you drop a file or set of files onto the
  50. droplet, the names of the files get passed to main() via the argv parameter. 
  51. I’ll present a small example of this later in the column.
  52. Once your project file is set up, create a new source code file named
  53. reference.java and type this source code into the file:
  54.  
  55. public class reference
  56. {
  57.     public static void main( String argv[] )
  58.     {
  59.         String    s1 = "Sample String";
  60.         String    s2 = "Sample String";
  61.         String    s3 = new String(s1); 
  62.  
  63.         if ( s1 == s2 )
  64.             System.out.println( "s1 is the same object as s2" );
  65.         else
  66.             System.out.println("s1 is not the same object as s2");
  67.  
  68.         if ( s1 == s3 )
  69.             System.out.println( "s1 is the same object as s3" );
  70.         else
  71.             System.out.println("s1 is not the same object as s3");
  72.     }
  73. }
  74.  
  75. Compile and run the program.  Here’s the results you should see in your stdout
  76. window:
  77.  
  78. s1 is the same object as s2
  79. s1 is not the same object as s3
  80.  
  81. Let’s take a walk through the source.  These three lines declare references to
  82. String objects:
  83.  
  84.         String    s1 = "Sample String";
  85.         String    s2 = "Sample String";
  86.         String    s3 = new String(s1); 
  87.  
  88. The first line creates a reference named s1 and also creates a new String
  89. object, initializing it with the literal “Sample String”.  The second line also
  90. creates a reference, this one named s2.  The question here is, was a new object
  91. created?  The answer is no.  The compiler checks to see if a literal with the
  92. value “Sample String” already exists.  Since such a literal does exist, the
  93. compiler doesn’t bother creating a new one.  It just creates the new object
  94. reference (s2) and makes it refer to the original literal.  Since there is no
  95. way to modify a literal, this strategy is pretty sure-fire.  Since pointers
  96. don’t exist in Java, the compiler has more freedom in allocating memory for
  97. objects.
  98. The third line of the set uses new to force the allocation of a new String
  99. object.  The String reference s1 is passed as a parameter to the String
  100. constructor.  So we end up with three String references: s1 and s2 both refer to
  101. the same String object, and s3 points to a second String object.
  102. To verify this theory, the first if-else statement uses the == operator to test
  103. if s1 is the same as s2.  Note that this tests whether s1 and s2 refer to the
  104. same object.  As proof, the result of the first if-else is:
  105.  
  106. s1 is the same object as s2
  107.  
  108. The second if-else compares s1 to s3.  Since we used new to force the allocation
  109. of a new String object, it is no surprise that the second if-else produces this
  110. result:
  111.  
  112. s1 is not the same object as s3
  113.  
  114. Take a few minutes to review the String methods; you’ll find them in the API
  115. Documentation folder in the file java.lang.String.html.  Pay specific attention
  116. to the compareTo(), equals(), and equalsIgnoreCase() methods.
  117. Copying an Object
  118. Before we move on to our second example, let’s talk about copying objects for a
  119. moment.  I was reading through my pile of Java books when I noticed an
  120. interesting discrepancy.  Several of the books specified that to duplicate an
  121. object, you should use the copy() method, inherited from java.lang.Object. 
  122. Alternatively, some sources recommended that you use the clone() method, also
  123. inherited from java.lang.Object.
  124. Being a curious son-of-a-gun, I wheeled over to Netscape and opened up
  125. java.lang.Object.html (in the folder API Documentation) to look for clone() and
  126. copy().  As it turns out, copy() isn’t there and clone() is there, but marked as
  127. protected and couldn’t be called from our main() class above.
  128. So what the heck was going on here?  After a few phone calls and emails to my
  129. Java buddies, I found out that copy() was dropped from the Java API between beta
  130. 1 and beta 2 of Java.  I also found out that the clone() method was changed to
  131. protected and that a new interface (we’ll talk about Java interfaces in a future
  132. column) was created, called the cloneable interface.  Basically, if you want
  133. your objects to be cloneable, they need to implement the cloneable interface. 
  134. To learn more about this, check out the file CloneNotSupportedException.html and
  135. this URL:  http://java.sun.com/JDK-beta2/changes.html
  136. The point of all this isn’t to push the cloneable interface.  I was just trying
  137. to save you from going through the head-banging exercise I just went through
  138. trying to figure out why copy() and clone() weren’t working as they were
  139. described in the books.  But if you want to learn how to make your objects
  140. cloneable, well, go right ahead...
  141.  
  142.  
  143.  
  144. Figure 1:  The Preferences dialog from the Hello droplet
  145. A Quick Droplet
  146. Our second example is a droplet, built using CodeWarrior.  Basically, the
  147. droplet is an application that sends the embedded classes to the virtual
  148. machine.  If any files are dropped on the droplet, their names are sent to
  149. main() in the argv parameter.
  150. To create a droplet, create your project using the droplet stationery.  Copy the
  151. resource file from the example “HelloWorld” droplet and edit it to change the
  152. creator signature and signature resource.  Next, edit the project preferences to
  153. reflect the application’s file name, the name of your class, and your creator
  154. (Figure 1).
  155. Here’s the droplet source code for the Hello droplet (note that the class is
  156. called HelloWorld but the droplet is called Hello):
  157.  
  158. public class HelloWorld
  159. {
  160.     public static void main(String argv[])
  161.     {
  162.         if (argv.length == 0 )
  163.             System.out.println("You launched Hello " +
  164.                     "without dropping anything on it.");
  165.         else
  166.         {
  167.             System.out.println("You launched Hello " +
  168.                     "dropping the following things:");
  169.  
  170.             for(int i = 0; i<argv.length; i++)
  171.                 System.out.println("Arg[" + 
  172.                         i + "]=" + argv[i]);
  173.         }
  174.     }
  175. }
  176.  
  177. Basically, this code prints one message if the droplet is launched without any
  178. files dropped on it, or else prints the list of files dropped on the droplet.
  179. Here’s the result of launching the Hello droplet without any files dropped on
  180. it:
  181.  
  182. You launched Hello without dropping anything on it.
  183.  
  184. Here’s the result when I dropped three files on the droplet:
  185.  
  186. You launched Hello dropping the following things:
  187. Arg[0]=/Macintosh%20HD/Test%20Files/File1
  188. Arg[1]=/Macintosh%20HD/Test%20Files/File2
  189. Arg[2]=/Macintosh%20HD/Test%20Files/File3
  190.  
  191. Note that the %20 in the string represents ASCII character 32, which is the
  192. space character.  20 in hex is 32.
  193. Our First Applet
  194. Before we go, here’s a taste of things to come: our first official applet.  As
  195. mentioned in last month’s column, a Java applet is a Java class that is derived
  196. from the class java.applet.Applet.  The java.applet.Applet class is described in
  197. the file java.applet.Applet.html.  Take a few minutes to look this page over.
  198. Our first applet takes advantage of the packages java.awt.Graphics and
  199. java.awt.Font.  Take a few minutes to look over the files java.awt.Graphics.html
  200. and java.awt.Font.html.  In fact, it is probably a good idea to look through the
  201. files in the API Documentation just to get an idea of what is in there.
  202. Our applet will consist of a single class, called hello, and a single method,
  203. called paint().  Our paint() overrides the standard paint() method that is part
  204. of the standard applet.  The default paint() method does nothing.  Ours will use
  205. a sequence of AWT (the Java equivalent to the Mac Toolbox) calls to draw the
  206. string “Hello, world!” in a pane or in a window (depending on the browser).
  207. Here’s the source code:
  208.  
  209. import java.awt.Font;
  210. import java.awt.Graphics;
  211.  
  212. public class hello extends java.applet.Applet
  213. {
  214.     public void paint( Graphics g )
  215.     {
  216.         Font f = new Font( "Chicago", Font.PLAIN, 36 );
  217.         
  218.         g.setFont( f );
  219.         g.drawString( "Hello, world!", 0, 30 );
  220.     }
  221. }
  222.  
  223. Notice that we don’t have a main() in our class.  Instead, our class follows the
  224. standard established for applets.  The paint() method will be called when it is
  225. time to draw our applet.  The Font object will be created using the Chicago font
  226. and is set to plain 36 point.  The Font object is passed to the setFont()
  227. method, making that font, style, and size current for the Graphics object g. 
  228. Next, the string “Hello, world!”  is drawn in g at the coordinates (0, 30) using
  229. the method drawString().
  230. To run this applet, you’ll need to first compile the source code into a class
  231. file (I called my class file hello.class) and then build a bit of HTML to launch
  232. the applet.  Here’s my HTML code:
  233.  
  234. <title>My test applet...</title>
  235. <hr>
  236. <applet code="hello.class" width=250 height=35></applet>
  237. <hr>
  238.  
  239. Of course, you might want to add more to your HTML, but this should do the
  240. trick.  Save the code as hello.html, and be sure hello.html and hello.class are
  241. in the same folder.  Now drag hello.html onto your applet runner. 
  242. Theoretically, you should see something like the window shown in Figure 2.
  243.  
  244. Figure 2.  Running the applet using CodeWarrior
  245. Till Next Month...
  246. To me, having the advanced windowing toolkit (AWT) is like having a copy of
  247. PowerPlant or the TCL.  The framework takes care of all the administrative
  248. detail so I can concentrate on filling in the details.  In next month’s column,
  249. we’ll do just that.  We’ll poke around the nooks and crannies, exploring the
  250. AWT.  See you then...
  251.